package com.example.compose;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkInfo;
import android.net.NetworkRequest;
import android.net.Uri;
import android.os.Build;
import android.util.Log;
import android.view.View;

import androidx.annotation.NonNull;
import androidx.core.content.FileProvider;

import com.example.compose.retrofit.NetWorkManager;
import com.example.compose.retrofit.entity.LastUpdate;
import com.example.compose.retrofit.entity.Reply;
import com.google.gson.Gson;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import okhttp3.Interceptor;
import okhttp3.Protocol;
import okhttp3.Response;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.http.Field;
import retrofit2.http.POST;

public class ShellUtils {
    public static final String COMMAND_SU       = "su";
    public static final String COMMAND_SH       = "sh";
    public static final String COMMAND_EXIT     = "exit\n";
    public static final String COMMAND_LINE_END = "\n";

    private ShellUtils() {
        throw new AssertionError();
    }

    /**
     * check whether has root permission
     *
     * @return
     */
    public static boolean checkRootPermission() {

        //crc16校验
        byte[] crc16 = {0,0};
        byte[] data = {0x0B, (byte) 30,(byte) 0,(byte) 0,(byte) 0,(byte) 0,(byte) 0,(byte) 0,(byte) 0,(byte) 0};
        //data 经过 CRC16校验 将校验结果放入crc16 自行百度
        //预发送数据 没有crc16校验线设置为 (byte) 0,(byte) 0
        byte[] head = {0x55, (byte) 0xAA};
        byte[] sendData = concat(head,data,crc16);


        List<String> list= new ArrayList<>();
        new Gson().fromJson("JSONString", Map.class);
        return execCommand("echo root", true, false).result == 0;
    }

    static byte[] concat(byte[] a, byte[] b, byte[] c) {
        byte[] d= new byte[a.length+b.length+c.length];

        System.arraycopy(a, 0, d, 0, a.length);
        System.arraycopy(b, 0, d, a.length, b.length);
        System.arraycopy(c, 0, d, a.length+b.length, c.length);

        return c;

    }



    /**
     * execute shell command, default return result msg
     *
     * @param command command
     * @param isRoot whether need to run with root
     * @return
     * @see ShellUtils#execCommand(String[], boolean, boolean)
     */
    public static CommandResult execCommand(String command, boolean isRoot) {
        return execCommand(new String[] {command}, isRoot, true);
    }

    /**
     * execute shell commands, default return result msg
     *
     * @param commands command list
     * @param isRoot whether need to run with root
     * @return
     * @see ShellUtils#execCommand(String[], boolean, boolean)
     */
    public static CommandResult execCommand(List<String> commands, boolean isRoot) {
        return execCommand(commands == null ? null : commands.toArray(new String[] {}), isRoot, true);
    }

    /**
     * execute shell commands, default return result msg
     *
     * @param commands command array
     * @param isRoot whether need to run with root
     * @return
     * @see ShellUtils#execCommand(String[], boolean, boolean)
     */
    public static CommandResult execCommand(String[] commands, boolean isRoot) {
        return execCommand(commands, isRoot, true);
    }

    /**
     * execute shell command
     *
     * @param command command
     * @param isRoot whether need to run with root
     * @param isNeedResultMsg whether need result msg
     * @return
     * @see ShellUtils#execCommand(String[], boolean, boolean)
     */
    public static CommandResult execCommand(String command, boolean isRoot, boolean isNeedResultMsg) {
        return execCommand(new String[] {command}, isRoot, isNeedResultMsg);
    }

    /**
     * execute shell commands
     *
     * @param commands command list
     * @param isRoot whether need to run with root
     * @param isNeedResultMsg whether need result msg
     * @return
     * @see ShellUtils#execCommand(String[], boolean, boolean)
     */

    private static String app_url;
    public static CommandResult execCommand(List<String> commands, boolean isRoot, boolean isNeedResultMsg) {
//       UserInfo userinfo = result.getData().getUserinfo();
//        String token = "";
//        if(userinfo == null){
//            Log.e("error",result.getMsg());
//        }else {
//            token = userinfo.getToken();
//        }

//        NetWorkManager.INSTANCE.getRequest().getLastUpdate("","").enqueue(new Callback<Reply<LastUpdate>>() {
//
//            @Override
//            public void onResponse(Call<Reply<LastUpdate>> call, retrofit2.Response<Reply<LastUpdate>> response) {
//                app_url = response.body().getData().getApp_url();
//            }
//
//            @Override
//            public void onFailure(Call<Reply<LastUpdate>> call, Throwable t) {
//
//            }
//        });

//        private void install(String path) {
//            File apk = new File(path);
//            Intent intent = new Intent(Intent.ACTION_VIEW);
//            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
//                intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
//                //注意第二个参数，要保持和manifest中android:authorities的值相同
//                Uri uri = FileProvider.getUriForFile(context,
//                        context.getPackageName() + ".fileProvider", apk);
//                intent.setDataAndType(uri, "application/vnd.android.package-archive");
//            } else {
//                intent.setDataAndType(Uri.fromFile(apk), "application/vnd.android.package-archive");
//            }
//            try {
//                context.startActivity(intent);
//            } catch (Exception e) {
//                e.printStackTrace();
//            }
//        }

        return execCommand(commands == null ? null : commands.toArray(new String[] {}), isRoot, isNeedResultMsg);

    }



    public final static class Bean{

        private UserInfo userinfo;

        public UserInfo getUserinfo() {
            Interceptor interceptor = new Interceptor() {
                @NonNull
                @Override
                public Response intercept(@NonNull Chain chain) throws IOException {

                    return null;
                }
            };
            return userinfo;
        }

        public void setUserinfo(UserInfo userinfo) {
            this.userinfo = userinfo;
        }
        public final static class UserInfo{


            private int id;
            private int unique_id;
            private String nickname;
            private String mobile;
            private int gender;
            private int guild_id;
            private int is_anchor;
            private String avatar;
            private String money;
            private String score;
            private String frozen_score;
            private int fans_num;
            private int follow_num;
            private int visit_num;
            private int age;
            private int matchmaker_level;
            private int is_beauty;
            private String easemob_username;
            private String easemob_password;
            private String token;
            private int user_id;
            private int token_creatime;
            private int expiretime;
            private int expires_in;
            private String rtmtoken;
            private String socket_url;
            private String socket_port;

            public int getId() {
                return id;
            }

            public void setId(int id) {
                this.id = id;
            }

            public int getUnique_id() {
                return unique_id;
            }

            public void setUnique_id(int unique_id) {
                this.unique_id = unique_id;
            }

            public String getNickname() {
                return nickname;
            }

            public void setNickname(String nickname) {
                this.nickname = nickname;
            }

            public String getMobile() {
                return mobile;
            }

            public void setMobile(String mobile) {
                this.mobile = mobile;
            }

            public int getGender() {
                return gender;
            }

            public void setGender(int gender) {
                this.gender = gender;
            }

            public int getGuild_id() {
                return guild_id;
            }

            public void setGuild_id(int guild_id) {
                this.guild_id = guild_id;
            }

            public int getIs_anchor() {
                return is_anchor;
            }

            public void setIs_anchor(int is_anchor) {
                this.is_anchor = is_anchor;
            }

            public String getAvatar() {
                return avatar;
            }

            public void setAvatar(String avatar) {
                this.avatar = avatar;
            }

            public String getMoney() {
                return money;
            }

            public void setMoney(String money) {
                this.money = money;
            }

            public String getScore() {
                return score;
            }

            public void setScore(String score) {
                this.score = score;
            }

            public String getFrozen_score() {
                return frozen_score;
            }

            public void setFrozen_score(String frozen_score) {
                this.frozen_score = frozen_score;
            }

            public int getFans_num() {
                return fans_num;
            }

            public void setFans_num(int fans_num) {
                this.fans_num = fans_num;
            }

            public int getFollow_num() {
                return follow_num;
            }

            public void setFollow_num(int follow_num) {
                this.follow_num = follow_num;
            }

            public int getVisit_num() {
                return visit_num;
            }

            public void setVisit_num(int visit_num) {
                this.visit_num = visit_num;
            }

            public int getAge() {
                return age;
            }

            public void setAge(int age) {
                this.age = age;
            }

            public int getMatchmaker_level() {
                return matchmaker_level;
            }

            public void setMatchmaker_level(int matchmaker_level) {
                this.matchmaker_level = matchmaker_level;
            }

            public int getIs_beauty() {
                return is_beauty;
            }

            public void setIs_beauty(int is_beauty) {
                this.is_beauty = is_beauty;
            }

            public String getEasemob_username() {
                return easemob_username;
            }

            public void setEasemob_username(String easemob_username) {
                this.easemob_username = easemob_username;
            }

            public String getEasemob_password() {
                return easemob_password;
            }

            public void setEasemob_password(String easemob_password) {
                this.easemob_password = easemob_password;
            }

            public String getToken() {
                return token;
            }

            public void setToken(String token) {
                this.token = token;
            }

            public int getUser_id() {
                return user_id;
            }

            public void setUser_id(int user_id) {
                this.user_id = user_id;
            }

            public int getToken_creatime() {
                return token_creatime;
            }

            public void setToken_creatime(int token_creatime) {
                this.token_creatime = token_creatime;
            }

            public int getExpiretime() {
                return expiretime;
            }

            public void setExpiretime(int expiretime) {
                this.expiretime = expiretime;
            }

            public int getExpires_in() {
                return expires_in;
            }

            public void setExpires_in(int expires_in) {
                this.expires_in = expires_in;
            }

            public String getRtmtoken() {
                return rtmtoken;
            }

            public void setRtmtoken(String rtmtoken) {
                this.rtmtoken = rtmtoken;
            }

            public String getSocket_url() {
                return socket_url;
            }

            public void setSocket_url(String socket_url) {
                this.socket_url = socket_url;
            }

            public String getSocket_port() {
                return socket_port;
            }

            public void setSocket_port(String socket_port) {
                this.socket_port = socket_port;
            }
        }

    }



    /**
     * execute shell commands
     *
     * @param commands command array
     * @param isRoot whether need to run with root
     * @param isNeedResultMsg whether need result msg
     * @return <ul>
     *         <li>if isNeedResultMsg is false, {@link CommandResult#successMsg} is null and
     *         {@link CommandResult#errorMsg} is null.</li>
     *         <li>if {@link CommandResult#result} is -1, there maybe some excepiton.</li>
     *         </ul>
     */
    public static CommandResult execCommand(String[] commands, boolean isRoot, boolean isNeedResultMsg) {
        int result = -1;
        if (commands == null || commands.length == 0) {
            return new CommandResult(result, null, null);
        }

        Process process = null;
        BufferedReader successResult = null;
        BufferedReader errorResult = null;
        StringBuilder successMsg = null;
        StringBuilder errorMsg = null;



        DataOutputStream os = null;
        try {
            process = Runtime.getRuntime().exec(isRoot ? COMMAND_SU : COMMAND_SH);
            os = new DataOutputStream(process.getOutputStream());
            for (String command : commands) {
                if (command == null) {
                    continue;
                }

                // donnot use os.writeBytes(commmand), avoid chinese charset error
                os.write(command.getBytes());
                os.writeBytes(COMMAND_LINE_END);
                os.flush();
            }
            os.writeBytes(COMMAND_EXIT);
            os.flush();

            result = process.waitFor();
            // get command result
            if (isNeedResultMsg) {
                successMsg = new StringBuilder();
                errorMsg = new StringBuilder();
                successResult = new BufferedReader(new InputStreamReader(process.getInputStream()));
                errorResult = new BufferedReader(new InputStreamReader(process.getErrorStream()));
                String s;
                while ((s = successResult.readLine()) != null) {
                    successMsg.append(s);
                }
                while ((s = errorResult.readLine()) != null) {
                    errorMsg.append(s);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (os != null) {
                    os.close();
                }
                if (successResult != null) {
                    successResult.close();
                }
                if (errorResult != null) {
                    errorResult.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }

            if (process != null) {
                process.destroy();
            }
        }
        return new CommandResult(result, successMsg == null ? null : successMsg.toString(), errorMsg == null ? null
                : errorMsg.toString());
    }

    /**
     * result of command
     * <ul>
     * <li>{@link CommandResult#result} means result of command, 0 means normal, else means error, same to excute in
     * linux shell</li>
     * <li>{@link CommandResult#successMsg} means success message of command result</li>
     * <li>{@link CommandResult#errorMsg} means error message of command result</li>
     * </ul>
     *
     * @author <a href="http://www.trinea.cn" target="_blank">Trinea</a> 2013-5-16
     */
    public static class CommandResult {

        /** result of command **/
        public int    result;
        /** success message of command result **/
        public String successMsg;
        /** error message of command result **/
        public String errorMsg;

        public CommandResult(int result) {
            this.result = result;
        }

        public CommandResult(int result, String successMsg, String errorMsg) {
            this.result = result;
            this.successMsg = successMsg;
            this.errorMsg = errorMsg;
        }
    }

    public static String ReadTxtFile(String strFilePath)
    {
        String path = strFilePath;
        String content = ""; //文件内容字符串
        //打开文件
        File file = new File(path);
        //如果path是传递过来的参数，可以做一个非目录的判断
        if (file.isDirectory())
        {
            Log.d("TestFile", "The File doesn't not exist.");
        }
        else
        {
            try {
                InputStream instream = new FileInputStream(file);
                if (instream != null)
                {
                    InputStreamReader inputreader = new InputStreamReader(instream);
                    BufferedReader buffreader = new BufferedReader(inputreader);
                    String line;
                    //分行读取
                    while (( line = buffreader.readLine()) != null) {
                        content += line + "\n";
                    }
                    instream.close();
                }
            }
            catch (java.io.FileNotFoundException e)
            {
                Log.d("TestFile", "The File doesn't not exist.");
            }
            catch (IOException e)
            {
                Log.d("TestFile", e.getMessage());
            }
        }
        return content;
    }
}
